home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / eulisp / mpfeel.lha / MPFeel / Modules / futures.em < prev    next >
Lisp/Scheme  |  1992-10-06  |  6KB  |  220 lines

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                           ;;
  3. ;;  EuLisp Module                     Copyright (C) University of Bath 1991  ;;
  4. ;;                                                                           ;;
  5. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  6.  
  7. ;
  8. ;; futures.em
  9. ;;
  10. ;;   General purpose-ish future package allowing constant limit and
  11. ;;   usage controlled creation.
  12. ;
  13.  
  14. (defmodule futures
  15.  
  16.   (standard0) ()
  17.  
  18.   ;
  19.   ;; Book Keeping.
  20.   ;;
  21.   ;;   We keep track of useful stats like the number of futures
  22.   ;;   created together with the number of currently active futures.
  23.   ;;   That kind of junk anyhow.
  24.   ;
  25.  
  26.   ;; Global accounting...
  27.  
  28.   (deflocal future-count-value 0)
  29.   (defconstant *fcv* (make-semaphore))
  30.  
  31.   (defun future-count () future-count-value)
  32.   (defun set-future-count (n) (setq future-count-value n))
  33.  
  34.   ((setter setter) future-count set-future-count)
  35.  
  36.   (defun increment-future-count () 
  37.     (open-semaphore *fcv*)
  38.     (setq future-count-value (+ future-count-value 1))
  39.     (close-semaphore *fcv*))
  40.  
  41.   (defun zero-future-count () (setq future-count-value 0))
  42.  
  43.   (export future-count increment-future-count zero-future-count)
  44.  
  45.   ;; Active acounting...
  46.  
  47.   (deflocal active-future-count-value 0)
  48.   (defconstant *afcv* (make-semaphore))
  49.  
  50.   (defun active-future-count () active-future-count-value)
  51.   (defun set-active-future-count (n) (setq active-future-count-value n))
  52.   ((setter setter) active-future-count set-active-future-count)
  53.  
  54.   (defun increment-active-future-count () 
  55.     (open-semaphore *afcv*)
  56.     (setq active-future-count-value (+ active-future-count-value 1))
  57.     (close-semaphore *afcv*))
  58.  
  59.   (defun decrement-active-future-count () 
  60.     (open-semaphore *afcv*)
  61.     (setq active-future-count-value (- active-future-count-value 1))
  62.     (close-semaphore *afcv*))
  63.  
  64.   (defun zero-active-future-count () (setq active-future-count-value 0))
  65.  
  66.   (export active-future-count zero-future-count)
  67.  
  68.   ;
  69.   ;; Future Structure.
  70.   ;;
  71.   ;;   In this hacked implementation really just a mailbox by another
  72.   ;;   name - hangs on to lots of useful information though.
  73.   ;
  74.  
  75.   (defstruct future-object ()
  76.  
  77.     ((function 
  78.         initarg function
  79.         accessor future-object-function)
  80.      (thread 
  81.         initarg thread
  82.         accessor future-object-thread)
  83.      (value 
  84.         accessor future-object-value)
  85.      (done  
  86.         initform nil
  87.     accessor future-object-done-p))
  88.  
  89.     constructor make-future-object
  90.     predicate futurep)
  91.  
  92.   (defmethod generic-prin ((f future-object) str)
  93.     (format str "#<future-object: ~a>" 
  94.         (if (future-object-done-p f) (future-object-value f)
  95.           'unresolved))
  96.     f)
  97.  
  98.   (defmethod generic-write ((f future-object) str)
  99.     (format str "#<future-object: ~s>" 
  100.         (if (future-object-done-p f) (future-object-value f)
  101.           'unresolved))
  102.     f)
  103.  
  104.   (export future-object future-object-value future-object-function
  105.       future-object-done-p make-future-object future-object-thread
  106.       futurep)
  107.  
  108.   ;
  109.   ;; Future Macro.
  110.   ;;
  111.   ;;   Just the usual syntax interface calling the function version.
  112.   ;
  113.  
  114.   (defmacro future exp
  115.     `(futurize (lambda () ,@exp)))
  116.  
  117.   (export future)
  118.  
  119.   ;
  120.   ;; Futurization.
  121.   ;;
  122.   ;;   Make a given closure into a future object depending on the
  123.   ;;   current creation heuristic.
  124.   ;
  125.  
  126.   (defun futurize (fn)
  127.     (if (not (really-create-future-p)) (fn)
  128.       (let*
  129.     ((task (make-thread
  130.          (lambda (future fun)
  131.            ((setter future-object-value) future (fun))
  132.            ((setter future-object-done-p) future t)
  133.            (decrement-active-future-count)
  134.            t)))
  135.      (future (make-future-object 'function fn 'thread task)))
  136.     ;; Enable the thread...
  137.     (increment-future-count)
  138.     (increment-active-future-count)
  139.     (thread-start task future fn)
  140.     future)))
  141.        
  142.   (export futurize)
  143.  
  144.   ;
  145.   ;; Future Evaluation.
  146.   ;;
  147.   ;;   Touch a future object for its value. Block until completed.
  148.   ;
  149.  
  150.   (defun future-value (fut)
  151.     (if (futurep fut)
  152.       (if (future-object-done-p fut) 
  153.     (future-value (future-object-value fut))
  154.     (progn
  155.       (thread-value (future-object-thread fut))
  156.       (future-value fut)))
  157.       fut))
  158.     
  159.   (export future-value)
  160.  
  161.   ;
  162.   ;; Creation Heuristic.
  163.   ;;
  164.   ;;   Should I really create or not.
  165.   ;
  166.  
  167.   (deflocal future-creation-heuristic-fn ())
  168.  
  169.   (defun future-creation-heuristic () 
  170.     future-creation-heuristic-fn)
  171.   (defun set-future-creation-heuristic (val)
  172.     (setq future-creation-heuristic-fn val))
  173.   ((setter setter) future-creation-heuristic set-future-creation-heuristic)
  174.  
  175.   (export future-creation-heuristic)
  176.  
  177.   (defun really-create-future-p ()
  178.     (future-creation-heuristic-fn))
  179.  
  180.   ;
  181.   ;; Creation Modes.
  182.   ;;
  183.   ;;  Modes of creation throttling.
  184.   ;
  185.  
  186.   (defmacro define-future-mode (name . body)
  187.     `(register-future-mode ',name (lambda () ,@body)))
  188.  
  189.   (defconstant *mode-table* (make-table eq))
  190.  
  191.   (defun register-future-mode (name fn)
  192.     ((setter table-ref) *mode-table* name fn))
  193.  
  194.   (deflocal current-mode ())
  195.  
  196.   (defun future-mode () current-mode)
  197.   (defun set-future-mode (name)
  198.     (let ((fn (table-ref *mode-table* name)))
  199.       (if (null fn)
  200.     (error (format () "future-mode: unknown mode - ~a" name) clock-tick)
  201.     (progn
  202.       (setq current-mode name)
  203.       ((setter future-creation-heuristic) fn)
  204.       name))))
  205.   ((setter setter) future-mode set-future-mode)
  206.  
  207.   (export future-mode)
  208.  
  209.   ;; Pre-defined modes.
  210.  
  211. ;;  (define-future-mode always t) ;; Always create
  212. ;;  (define-future-mode never ()) ;; Never create
  213.   
  214. ;;  ((setter future-mode) 'always)
  215.  
  216.   ((setter future-creation-heuristic) 
  217.     (lambda () (< (active-future-count) 3)))
  218. )
  219.  
  220.